package org.nicocube.airain.app.client.ui;

import java.util.Map;

import org.nicocube.airain.app.client.ui.PlayerSubscriptionPanel.I18nConstants;
import org.nicocube.airain.domain.client.character.Gender;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.Widget;

class GenderFieldWidget extends Composite implements HasValue<Gender> {
	final HorizontalPanel genderPanel = new HorizontalPanel();
	private boolean valueChangeHandlerInitialized = false;

	public GenderFieldWidget(String name, Constants constants) {
		Map<String, String> genderOptions = ((I18nConstants)constants).genders();

		Gender g;
		RadioButton rb;
		
		g = Gender.Male;
		rb = new RadioButton(name,
				genderOptions.get(g.name()));
		rb.setFormValue(g.name());
		genderPanel.add(rb);

		g = Gender.Female;
		rb = new RadioButton(name,
				genderOptions.get(g.name()));
		rb.setFormValue(g.name());
		genderPanel.add(rb);
		
		initWidget(genderPanel);
	}

	@Override
	protected void onLoad() {
		super.onLoad();
	}
	
	@Override
	public Gender getValue() {
		for (Widget rb : genderPanel) {
			if (((RadioButton)rb).getValue())
				return Gender.valueOf(((RadioButton)rb).getFormValue());
		}
		return Gender.Unknown;
	}

	@Override
	public void setValue(Gender value) {
		setValue(value, false);
	}

	@Override
	public void setValue(Gender value, boolean fireEvents) {
		if (value == null) {
			value = Gender.Unknown;
		}

		boolean noChange = true;

		for (Widget rb : genderPanel) {
			if (Gender.valueOf(((RadioButton)rb).getFormValue()) == value) {
				noChange = ((RadioButton)rb).getValue();
				((RadioButton)rb).setValue(true);
			} else {
				((RadioButton)rb).setValue(false);
			}
		}	

		if (noChange) {
			return;
		}
		if (fireEvents) {
			ValueChangeEvent.fire(this, value);
		}
	}

	@Override
	public HandlerRegistration addValueChangeHandler(
			ValueChangeHandler<Gender> handler) {
		// Is this the first value change handler? If so, time to add handlers
		if (!valueChangeHandlerInitialized) {
			ensureDomEventHandlers();
			valueChangeHandlerInitialized = true;
		}
		return addHandler(handler, ValueChangeEvent.getType());
	}

	protected void ensureDomEventHandlers() {
		for (final Widget rb : genderPanel) {
			((RadioButton)rb).
			addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {
					// Checkboxes always toggle their value, no need to compare
					// with old value. Radio buttons are not so lucky, see
					// overrides in RadioButton
					ValueChangeEvent.fire(GenderFieldWidget.this, Gender.valueOf(((RadioButton)rb).getFormValue()));
				}
			});
		}
	}

}
